package edu.ucsd.db.bassarisk.algebra.logical;

import java.util.Collection;
import java.util.List;

import edu.ucsd.db.bassarisk.algebra.logical.function.Function;
import edu.ucsd.db.bassarisk.columndef.DataColumnDefinition;
import edu.ucsd.db.bassarisk.query.binding.Bindings.AggregatedValueBinding;
import edu.ucsd.db.bassarisk.query.binding.Bindings.Binding;
import edu.ucsd.db.bassarisk.query.binding.Bindings.MapFunctionValueBinding;
import edu.ucsd.db.bassarisk.query.predicate.PositionPredicates.PositionPredicate;

public class LogicalPlanner {
  public static LogicalOperator createAggregateAll(List<AggregatedValueBinding> aggs,
                                            LogicalOperator subPlan) {
    return new AggregateAll(aggs, subPlan);
  }

  public static LogicalOperator
      createAggregateWithin(final List<AggregatedValueBinding> aggs,
                        final LogicalOperator subPlan) {
    return new AggregateWithin(aggs, subPlan);
  }

  public static LogicalOperator
      createIntersection(final List<LogicalOperator> intersectPlans) {
    if (intersectPlans.size() == 1) {
      return intersectPlans.get(0);
    } else {
      return new Intersection(intersectPlans);
    }
  }

  public static LogicalOperator createJoin(final List<LogicalOperator> subPlans) {
    return new Join(subPlans);
  }

  public static LogicalOperator
      createJoinWithin(final List<LogicalOperator> containedPlans) {
    return new JoinWithin(containedPlans);
  }

  public static LogicalOperator createMap(final List<MapFunctionValueBinding> maps,
                                          final LogicalOperator subPlan) {
    return new Map(maps, subPlan);
  }

  public static LogicalOperator createScan(final DataColumnDefinition column,
                                           final String filterValue,
                                           final Binding binding) {
    return new Scan(column, filterValue, binding);
  }

  public static
      LogicalOperator
      createSelect(LogicalOperator subPlan, Collection<PositionPredicate> predicates) {
    return new Select(predicates, subPlan);
  }

  public static LogicalOperator
      createUnion(final List<LogicalOperator> unionPlans) {
    if (unionPlans.size() == 1) {
      return unionPlans.get(0);
    } else {
      return new Union(unionPlans);
    }
  }

  public static LogicalOperator createConstantTuple(Function f) {
    return new ConstantTuple(f);
  }

  public static LogicalOperator createWithinContext(final LogicalOperator context,
                                                    final LogicalOperator subplan) {
    return new WithinContext(context, subplan);
  }
}
